#include <syslog.h>
#include <fcntl.h>
#include <sys/resource.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>

void daemonize(const char *cmd){
    int i, fd0, fd1, fd2;
    pid_t pid;
    struct rlimit r1;
    struct sigaction sa;

    /*
        1.Clear file creation mask
    */
    umask(0);

    /*
        2.Get maximum number of file descriptors
    */
    if(getrlimit(RLIMIT_NOFILE, &r1) < 0){
        printf("can't get file limit\n");
        exit(0);
    }

    /*
        3.Become a session leader to lose controlling TTY
    */
    if((pid = fork()) < 0){
        printf("fork error\n");
        exit(0);
    }else if(pid != 0){
        /*parent*/
		exit(0);
    }
    setsid();
    /*
        4.Ensure future opens won't allocate controlling TTYS
    */
    sa.sa_handler = SIG_IGN;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    if(sigaction(SIGHUP, &sa, NULL) < 0){
        printf("sigaction error\n");
        exit(0);
    }

    if((pid = fork()) < 0){
        printf("fork error\n");
        exit(0);
    }else if(pid != 0){
        /*parent*/
        exit(0);
    }
    /*
        5.Change the current working directory to the root so
        we won't prevent file systems from being unmounted.
    */
    if(chdir("/") < 0){
        printf("chdir error\n");
        exit(0);
    }
    
    /*
        6.Close all open file descriptors.
    */
    if(r1.rlim_max == RLIM_INFINITY){
        r1.rlim_max = 1024;
    }
    for(i = 0; i < r1.rlim_max; i++){
        close(i);
    }

    /*
        7.Attach file descriptors 0,1,and 2 to /dev/null.
    */
    fd0 = open("/dev/null", O_RDWR);
    fd1 = dup(0);
    fd2 = dup(0);
    /*
        8.Initialize the log file.
    */
    openlog(cmd, LOG_CONS | LOG_PID, LOG_DAEMON);
    if(fd0 != 0 || fd1 != 1 || fd2 != 2){
        syslog(LOG_ERR, "unexpected file descriptors");
        exit(0);
    }
}

/*
int main(){
	daemonize("Test");
    syslog(LOG_ERR, "test");

	sleep(100);
}
*/
